package com.beardedcoder.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;

/**
 * The intention is for this file to handle writing objects to files
 * @author Rob_2
 *
 */
public class UtilObjectSerialiser {
	
	/**
	 * This will take the object and write it out to the file. 
	 * If the process fails it will throw the error
	 * @param obj
	 * @param file
	 * @return
	 * @throws IOException 
	 */
	public static void write(Object obj, File file) throws IOException {
		
		if (file == null || file.isFile() == false) {
			throw new IllegalArgumentException("file provided is not valid");
		}
		if (obj == null) {
			throw new IllegalArgumentException("object to serialize was null");
		}
		
		FileOutputStream fileOutputSteam = new FileOutputStream(file);
		write(obj, fileOutputSteam);	
	}

	/**
	 * 
	 * @param obj
	 * @param fileOutputSteam
	 * @throws IOException
	 */
	public static void write(Object obj, FileOutputStream fileOutputSteam)
			throws IOException {
		ObjectOutputStream objStream = new ObjectOutputStream(fileOutputSteam);
		try {
			objStream.writeObject(obj);			
		} finally {
			objStream.flush();
			objStream.close();
			objStream = null;
			fileOutputSteam.flush();
			fileOutputSteam.close();
			fileOutputSteam = null;
		}
	}
	
	/**
	 * This will read from the file and return any object(s) contained within. 
	 * To be generic it will simply return an Object. This needs to be known on the
	 * calling side and cast appropriately. 
	 * It's possible for return to be null (eg, on error) therefore it should be checked. 
	 * @param file
	 * @return
	 * @throws IOException 
	 * @throws StreamCorruptedException 
	 * @throws ClassNotFoundException 
	 */
	public static Object read (File file) throws StreamCorruptedException, IOException, ClassNotFoundException {
		
		if (file == null || file.isFile() == false) {
			throw new IllegalArgumentException("file provided is not valid");
		}
		
		Object toReturn = null;
		
		FileInputStream fin = new FileInputStream(file);
		toReturn = read(fin);
		
		return toReturn;
	}
	
	/**
	 * 
	 * @param fin
	 * @return
	 * @throws StreamCorruptedException
	 * @throws IOException
	 * @throws OptionalDataException
	 * @throws ClassNotFoundException
	 */
	public static Object read (FileInputStream fin)
			throws StreamCorruptedException, IOException,
			OptionalDataException, ClassNotFoundException {
		Object toReturn = null;
		ObjectInputStream oin = new ObjectInputStream(fin);
		try {
			toReturn = oin.readObject();
		} finally {
			oin.close();
			oin = null;
			fin.close();
			fin = null;
		}
		return toReturn;
	}
}
